#ifndef PARAMMANAGER_H
#define PARAMMANAGER_H

#include <stdint.h>
#include <common/array.h>

class LockableStorage;

class ParamManager {
public:
	enum {
		ADDRESS				= 0
		, TYPE				= 1
		, VCRUISE			= 2
		, VROTATE			= 3
		, VRETRACT			= 4
		, VAPPROACH			= 5
		, BAROALT_INITIAL	= 6
		, BAROALT_MINIMUM	= 7
		, BAROALT_PARACHUTE	= 8
		, ELEVATOR_TAKEOFF	= 9
		, ELEVATOR_LANDING  = 10
		, THROTTLE_IDLE		= 11
		, VMIN				= 12
		, VMIN_PITCH		= 13
		, PITCH_TAKEOFF		= 14
		, PITCH_CLIMB		= 15
		, PITCH_FLARE		= 16
		, VTAKEOFFSTOP		= 17
		, TAKEOFFTHROTTLE	= 18
		, MANUAL_MAXROLL	= 19
		, MANUAL_MAXPITCH	= 20
		, PHOTO_GAP			= 21
		, PHOTO_BEGIN 		= 22
		, PHOTO_END 		= 23
		, Z_OFFSET			= 24
		, AIRSPEED_DEADZONE	= 25
		, FUEL_K 			= 26
		, FUEL_ALPHA 		= 27
		, VFBW				= 28
		, PITCH_THROTTLE	= 29
			
		, WROLL_TO_AILERON 	= 30
		, WROLL_KP			= 30
		, WROLL_KI			= 31
		, WROLL_KD			= 32
		, WROLL_MIN			= 33
		, WROLL_MAX			= 34

		, WPITCH_TO_ELEVATOR = 35
		, WPITCH_KP			= 35
		, WPITCH_KI			= 36
		, WPITCH_KD			= 37
		, WPITCH_MIN		= 38
		, WPITCH_MAX		= 39

		, WYAW_TO_RUDDER	= 40
		, WYAW_KP			= 40
		, WYAW_KI			= 41
		, WYAW_KD			= 42
		, WYAW_MIN			= 43
		, WYAW_MAX			= 44

		, ALTITUDE_TO_PITCH = 45
		, ALTITUDE_KP		= 45
		, ALTITUDE_KI		= 46
		, ALTITUDE_KD		= 47
		, ALTITUDE_MIN		= 48
		, ALTITUDE_MAX		= 49

		, VSPEED_TO_PITCH	= 50
		, VSPEED_KP			= 50
		, VSPEED_KI			= 51
		, VSPEED_KD			= 52
		, VSPEED_MIN		= 53
		, VSPEED_MAX		= 54	
			
		, HEADING_TO_RUDDER	= 55
		, HEADINGGND_KP		= 55
		, HEADINGGND_KI		= 56
		, HEADINGGND_KD		= 57
		, HEADINGGND_MIN	= 58
		, HEADINGGND_MAX	= 59

		, IAS_TO_THROTTLE	= 60
		, IAST_KP			= 60
		, IAST_KI			= 61
		, IAST_KD			= 62
		, IAST_MIN			= 63
		, IAST_MAX			= 64

		, TRACK_K1			= 65
		, TRACK_K2			= 66
		, TRACKAPP_K1		= 67
		, TRACKAPP_K2		= 68
		
		, DEBUG_BITS		= 69
			
		, ROLL_TO_WROLL_KP  = 70
		, ROLL_TO_WROLL_MAX	= 71
		, PITCH_TO_WPITCH_KP = 72
		, PITCH_TO_WPITCH_MAX = 73
		, WSTABILISATION	= 74

		, FUTABA_FILTER		= 75
		, TRACK_TO_COURSE_KP = 76
		, DESCEND_PROFILE	= 77
			
		, ENGINE_START_TIME1 = 78
		, ENGINE_START_THR1 = 79
		, ENGINE_START_TIME2 = 80
		, ENGINE_START_THR2 = 81
		, ENGINE_START_TIME3 = 82
		, ENGINE_START_THR3 = 83
		, ENGINE_START_TEMP = 84

		, ROLL_TO_AILERON 	= 85
		, ROLL_KP			= 85
		, ROLL_KI			= 86
		, ROLL_KD			= 87
		, ROLL_MIN			= 88
		, ROLL_MAX			= 89

		, PITCH_TO_ELEVATOR = 90
		, PITCH_KP			= 90
		, PITCH_KI			= 91
		, PITCH_KD			= 92
		, PITCH_MIN			= 93
		, PITCH_MAX			= 94

		, NUMOFPARAMS
	};

	enum {
		  DEBUG_BITS_VANE_IND = (1 << 0)
		, DEBUG_BITS_IMUW_IND = (1 << 1)
		, DEBUG_BITS_RAW_ALT = (1 << 2)
		, DEBUG_BITS_PARAM_SAFETY = (1 << 3)
		, DEBUG_BITS_DONT_RESERVE_ADS = (1 << 4)
	};

	ParamManager(LockableStorage *storage);
	
	float getFloat(int index);
	uint32_t getUint(int index);	
	bool read(int index, uint32_t &value);
	bool read(int index, float &value);
	void setFloat(int index, float value);
	void write(int index, uint32_t value);
	uint32_t getWriteCounter() const;
	
private:
	ParamManager();	
	uint16_t getAddr(int index) const;
	void initDefaults();
	void logError() const;
	
	static const uint16_t start_addr_;
	static const int sizeof_param_;
	uint32_t writeCounter_;
	LockableStorage *storage_;
	
	Array<float> defaults_;
};


#endif

